const response = require("../../utils/response.js");
const validate = require("../../utils/validate.js");
const videoService = require("../services/videoService.js");
const { URLSearchParams } = require('url');
const { deleteVideoRules, updateVideoRules, getVideoRules } = require("../validations/videoValidation.js");
const { createReadStream, createWriteStream, existsSync, unlinkSync, promises } = require("fs");
const path = require("path");
const { parseRange, waitTime } = require("../../utils/index.js");
const userService = require("../services/userService.js");
const Video = require("../models/Video.js");
const { Op } = require("sequelize");



class VideoController {
    async addVideo(ctx) {
        try {
            const { file } = ctx.request.files;
    
            if (!file) {
                response.error(ctx, '请上传文件');
                return;
            }
    
            const ext = path.extname(file.originalFilename);
            const filename = Date.now() + ext;
            const filePath = path.resolve(process.env.VIDEO_PATH, filename);
    
            const readStream = createReadStream(file.filepath);
            const writeStream = createWriteStream(filePath);
    
            await new Promise((resolve, reject) => {
                readStream.pipe(writeStream);
                readStream.on('end', resolve);
                readStream.on('error', reject);
                writeStream.on('error', reject);
            });
    
            const { id } = await videoService.addVideo({ filename });
            if (!id > 0) throw '文件上传失败';
    
            response.success(ctx, null);
    
        } catch (err) {
            console.error(err);
            response.error(ctx, err);
        }
    }
    async deleteVideo(ctx) {
        try {
            const { id } = await validate(ctx, deleteVideoRules);
            const videoInstance = await videoService.getVideoById(id);
            if(!videoInstance) throw '未找到视频';

            await videoInstance.destroy();
            unlinkSync(process.env.VIDEO_PATH + '/' + videoInstance.dataValues.filename);

            response.success(ctx, id, '删除成功')
        } catch (err) {
            console.log(err)
            response.error(ctx, err);
        }
    }
    async updateVideo(ctx) {
        try {
            const videoData = await validate(ctx, updateVideoRules);
            await videoService.updateVideo(videoData);
            response.success(ctx, '修改成功')
        } catch (err) {
            console.log(err)
            response.error(ctx, err);
        }
    }
    async getVideo(ctx) {
        try {
            const { filename } = await validate(ctx, getVideoRules);
            const requestRange = ctx.headers['range'] || 'bytes=0-';
            let videoPath = process.env.VIDEO_PATH + '/' + filename

            if(!existsSync(videoPath)) throw '文件不存在';

            const stat = await promises.stat(videoPath);
            const fileSize = stat.size;
            // 解析 Range 请求头
            const { start, end } = parseRange(requestRange, fileSize);

            // 设置响应头
            ctx.set('Content-Type', 'video/mp4');
            ctx.set('Accept-Ranges', 'bytes');
            ctx.set('Content-Length', (end - start + 1).toString());
            ctx.set('Content-Range', `bytes ${start}-${end}/${fileSize}`);


            // 发送部分视频数据
            ctx.status = 206; // Partial Content
            ctx.body = await promises.readFile(videoPath, { start, end });
        } catch (err) {
            console.log(err)
            response.error(ctx, err);
        }
    }
    async getVideoListByPage(ctx) {
        const usp = new URLSearchParams(ctx.querystring);
        let page = Number(usp.get('page')) || 1;
        let limit = Number(usp.get('limit')) || 10;
        let keyword = usp.get('keyword') || '';
        let status = usp.get('status') || '';
        let sort = usp.get('sort') || 'DESC';
        let updatePage = usp.get('updatePage') || 'yes';
        // await waitTime(5000);
        try {
            const { rows, count } = await videoService.getVideoListByPage(page, limit, keyword, status, sort);
            response.success(ctx, {
                page,
                limit,
                rows,
                total: count
            });

            // 如果是已登录用户就更新观看到的视频页数
            if(ctx.state.user && updatePage === 'yes'){
                const userInstance = await userService.getUserById(ctx.state.user.id);
                userInstance.setDataValue('page', page);
                userInstance.save();
            }
        } catch (err) {
            console.log(err)
            response.error(ctx, err);
        }
    }
    // 恢复用户播放视频列表
    async reStoreVideoList(ctx){
        const usp = new URLSearchParams(ctx.querystring);
        let limit = Number(usp.get('limit')) || 10;
        try {
            let user = ctx.state.user;
            if(user){
                const userInstance = await userService.getUserById(user.id);
                const page = userInstance.dataValues.page;
                const { rows, count } = await videoService.getVideoListByPage(page, limit, '', '', 'ASC');
                response.success(ctx, {
                    page,
                    limit,
                    rows,
                    total: count
                });
            }else{
                const { rows, count } = await videoService.getVideoListByPage(1, limit, '', '', 'ASC');
                response.success(ctx, {
                    page: 1,
                    limit,
                    rows,
                    total: count,
                });
            }

        } catch (err) {
            console.log(err)
            response.error(ctx, err);
        }
    }
    async getAllVideos(ctx) {
        try {
            const rows = await videoService.getAllVideos();
            response.success(ctx, rows);
        } catch (err) {
            console.log(err, 'err')
            response.error(ctx, err);
        }
    }
}


module.exports = new VideoController();